package cn.wolfcode.luowowo.controller;

import cn.wolfcode.luowowo.annotation.RequireLogin;
import cn.wolfcode.luowowo.cache.service.IStrategyStatisVORedisService;
import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.domain.UserInfo;
import cn.wolfcode.luowowo.domain.Visitor;
import cn.wolfcode.luowowo.exception.LogicException;
import cn.wolfcode.luowowo.query.StrategyCommentQuery;
import cn.wolfcode.luowowo.service.IUserInfoService;
import cn.wolfcode.luowowo.service.IVisitorService;
import cn.wolfcode.luowowo.swagger2.PersonTest;
import cn.wolfcode.luowowo.util.JsonResult;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("users")
@Api(value = "用户资源",description = "用户资源控制器")
public class UserInfoController {


    // 发送短信功能(获取配置文件中的网关接口地址和秘钥)
    //@Value("${sms.url}")
    private String smsUrl;
    //@Value("${sms.appkey}")
    private String appKey;



    @Autowired
    private IUserInfoService userInfoService;

    @Autowired
    private IUserInfoRedisService userInfoRedisService;

    @Autowired
    private IStrategyStatisVORedisService strategyStatisVORedisService;

    // 拓展(小测)
    @Autowired
    private IVisitorService visitorService;


    @GetMapping("/get")
    public Object get(String id){
        // return userInfoService.get(id);
        return JsonResult.success(userInfoService.get(id));// 获取头像

    }

    // 验证手机号是否存在数据库
    @GetMapping("/checkPhone")
    public Object checkPhone(String phone){

        // 判断手机号是否存在
        boolean ret = userInfoService.checkPhone(phone);
        return !ret;//感叹号:返回值要看前端js里写的逻辑
    }

    // 发送短信
    @GetMapping("/sendVerifyCode")
    public Object sendVerifyCode(String phone){

        // 向手机里发送短信
        userInfoService.sendVerifyCode(phone, smsUrl, appKey);
        // 返回成功的状态
        return JsonResult.success();
    }

    // 完成用户注册
    @ApiOperation(value = "注册功能",notes = "其实就是新增用户")//swagger工具
    @ApiImplicitParams({// swagger开发文档api工具:散参数类型贴注解方式
            @ApiImplicitParam(value = "手机号",name = "phone",dataType = "String",required = true),//required是否必填
            @ApiImplicitParam(value = "昵称",name = "nickname",dataType = "String",required = true),
            @ApiImplicitParam(value = "密码",name = "password",dataType = "String",required = true),
            @ApiImplicitParam(value = "确认密码",name = "rpassword",dataType = "String",required = true),
            @ApiImplicitParam(value = "验证码",name = "verifyCode",dataType = "String",required = true),
    })
    @PostMapping("/regist")
    public Object regist(String phone,String nickname, String password, String rpassword, String verifyCode){

        // 用户注册时需要带入的手机号参数,昵称参数,密码参数,重置密码参数,验证码参数
        userInfoService.regist(phone, nickname, password, rpassword, verifyCode);
        // 返回成功的状态 LogicException
        return JsonResult.success();

//        try{
//            // 用户注册时需要带入的手机号参数,昵称参数,密码参数,重置密码参数,验证码参数
//            userInfoService.regist(phone, nickname, password, rpassword, verifyCode);
//
//         // 存在问题 异常分两种,一种需要提示用户, 第二种是系统bug不能让用户看到(拆分异常,一种提示用户,一种不需要提示用户)
//        }catch (LogicException e){//自定义异常:给用户看的异常
//            e.printStackTrace();
//            // 若用户输入框某个参数没输入,则返回提示信息
//            return new JsonResult<>(JsonResult.CODE_ERROR_PARAM,e.getMessage(),null);
//        }catch (Exception e){
//            // 处理输入框内为空时,把提示信息返回前端页面(若不try提示信息会显示在控制台)
//            // 失败返回页面错误信息
//            // 存在问题 异常分两种,一种需要提示用户, 第二种是系统bug不能让用户看到(拆分异常,一种提示用户,一种不需要提示用户)
//            e.printStackTrace();
//            // 系统异常
//            return JsonResult.defaultError();
//        }
    }

    // 第一次请求:用户登录功能实现
    @PostMapping("/login")
    //@RequireLogin
    public Object login(String username, String password){

        // 1.登录成功返回用户对象(从数据库查询user对象)
        UserInfo user = userInfoService.login(username, password);

        // 用户对象是否为null,若为空没登录,给出提示,若不为空,登录成功,提示(service层处理)

        // 2.创建token,将token对象添加到redis缓存中
        String token = userInfoRedisService.setToken(user);

        // 3.页面需要:返回token 和 用户对象
        Map<String, Object> map = new HashMap<>();
        map.put("token",token);
        map.put("user",user);
        // 返回成功的状态(带有数据)
        return JsonResult.success(map);
    }

    // 第二次请求:用户登录功能实现
    @RequireLogin // 贴了此注解,表示请求拦截,不贴不拦截
    @GetMapping("/currentUser")//假设 页面发起请求带有token这个请求
    public Object currentUser(HttpServletRequest request){

        // 从请求对象中获取token值
        String token = request.getHeader("token");
        // 通过token从Redis获取当前登录用户对象
        UserInfo user = userInfoRedisService.getUserByToken(token);

        // 返回成功的状态(带数据)
        return JsonResult.success(user);
    }

    //用户攻略收藏
    @GetMapping("/strategies/favor")
    public Object comments(String userId){

        List<String> ids = strategyStatisVORedisService.getUserStrategyFavor(userId);

        return JsonResult.success(ids);
    }

    // 访问数+1
    /*@GetMapping("/personal/homepage")
    public Object personalHomepage(String ids){
        List<Visitor> visitors = visitorService.listAll();
        return JsonResult.success();
    }*/
    // 测试swagger开发文档api工具封装类型的参数(此接口/方法在此项目中不起作用:只为测试用)
    @ApiResponses({
            @ApiResponse(code=200,message="用户注册成功"),
            @ApiResponse(code=401,message="访问权限异常"),
            @ApiResponse(code=403,message="访问被禁止"),
            @ApiResponse(code=404,message="无法找到页面"),
            @ApiResponse(code=500,message="程序出错")
    })
    @GetMapping("/person")
    @ApiOperation(value = "(假的测试)注册功能",notes = "新增用户")
    public Object personalHomepage(PersonTest personTest) {
        return JsonResult.success(personTest);
    }
}
